package com.macoli.android.permissionx

import android.content.pm.PackageManager
import android.os.Bundle
import android.util.Log
import androidx.core.app.ActivityCompat
import androidx.core.content.ContextCompat
import androidx.fragment.app.FragmentActivity
import com.macoli.android.permissionx.internal.PermissionXFragment
import kotlin.coroutines.resume
import kotlin.coroutines.suspendCoroutine

class PermissionX {
    companion object {
        const val TAG = "permissionx"
        var permissionxLog : Boolean = false
        fun openLog(){
            permissionxLog = true
        }

        fun log(message: String) {
            Log.d(TAG , message)
        }
    }
}



/**
 * Represents the result of a permission request.
 *
 * @property permission The permission requested.
 * @property granted Indicates whether the permission was granted by the user.
 * @property hasRefuse Indicates whether the user has previously refused permission requests and might need guidance.
 */
data class PermissionXResult(
    var permission: String,
    var granted: Boolean,
    /**
     * The user has previously refused permission requests and needs a pop-up window to guide the user to set the interface
     * */
    var hasRefuse: Boolean = false
)

/**
 * Represents the result of multiple permission requests.
 *
 * @property allGranted Indicates whether all permissions were granted.
 * @property resultList A map containing permission results, where keys are permission names and values are PermissionXResult objects.
 */
class PermissionXResultMap(
    var allGranted: Boolean,
    val resultList: HashMap<String , PermissionXResult> = HashMap()
): Map<String, PermissionXResult> by resultList {

}

/**
 * Requests the specified permissions from the user asynchronously within a coroutine.
 *
 * @param fragmentActivity The FragmentActivity instance from which the permissions are requested.
 * @param permissionList A list of permissions to be requested from the user.
 */
suspend fun requestPermissions(
    fragmentActivity: FragmentActivity,
    permissionList: ArrayList<String>
): PermissionXResultMap = suspendCoroutine { continuation ->
    PermissionX.log("requestPermission $permissionList")
    val permissionResultMap = PermissionXResultMap(true)
    for (i in permissionList.size - 1 downTo 0) {
        val permission = permissionList[i]
        val result = ContextCompat.checkSelfPermission(fragmentActivity, permission)
        if(result != PackageManager.PERMISSION_GRANTED) {
            val hasRefuse = ActivityCompat.shouldShowRequestPermissionRationale(fragmentActivity , permission)
            if (hasRefuse) {
                permissionResultMap.allGranted = false
                val permissionXResult = PermissionXResult(permission , false , true)
                permissionResultMap.resultList[permission] = permissionXResult
                permissionList.removeAt(i)
            }
        } else {
            val permissionXResult = PermissionXResult(permission , true , false)
            permissionResultMap.resultList[permission] = permissionXResult
            permissionList.removeAt(i)
        }
    }
//    PermissionX.log("requestPermission $permissionList , $permissionResult")
    if (permissionList.isEmpty()) {
        continuation.resume(permissionResultMap)
    } else {
        val permissionFragment = PermissionXFragment()
        val args = Bundle()
        args.putStringArrayList(PermissionXFragment.ARG_PERMISSION, permissionList)
        permissionFragment.arguments = args
        permissionFragment.callback = { granted , resultList ->
            if (resultList != null) {
                for (permissionResult in resultList) {
                    permissionResultMap.resultList[permissionResult.permission] = permissionResult
                }
            }
            permissionResultMap.allGranted = permissionResultMap.allGranted && granted
            continuation.resume(permissionResultMap)
        }
        fragmentActivity.supportFragmentManager.beginTransaction().add(permissionFragment,
            PermissionXFragment.TAG_PERMISSION_FRAGMENT
        ).commit()
        PermissionX.log("requestPermission $permissionList add fragment")
    }
}